#include "pthread.h"
#include "stdio.h"
#include "errno.h"

#include "alarm_data_mutex.h"

void* alarm_thread(void* arg)
{
	alarm_t* p_alarm = NULL;
	int sleep_time;
	int status;
	time_t now;
	int wait_ret_val, timedwait_ret_val;
	struct timespec cond_time;
	int expired;

	status = pthread_mutex_lock(&alarm_mutex);
	if(status != 0) {
		printf("&alarm_thread: lock failed!\n");
		exit(0);
	}

	while(1) {
		expired = 0;
		current_time = 0;
		while(NULL == alarm_list) {
			wait_ret_val = pthread_cond_wait(&alarm_cond, &alarm_mutex);
			if(0 != wait_ret_val) {
				printf("&alarm_thread: fail to wait predication. "
						"program exit!\n");
				exit(0);
			}
		}

		p_alarm = alarm_list;
		alarm_list = alarm_list->next;
		now = time(NULL);

		if(p_alarm->time <= now) {
			expired = 1;
		}
		else {
			cond_time.tv_sec = p_alarm->time;
			cond_time.tv_nsec = 0;
			current_time = p_alarm->time;
			while(current_time == p_alarm->time) {
				timedwait_ret_val = pthread_cond_timedwait(&alarm_cond,
						&alarm_mutex, &cond_time);
				if(ETIMEDOUT == timedwait_ret_val) {
					expired = 1;
					break;
				}
				if(0 != timedwait_ret_val) {
					printf("&alarm_thread: fail to wait for time out, "
							"program exit!\n");
					exit(0);
				}
			}
		}

		if(1 == expired) {
			printf("When alarm expires: %d, %s\n", p_alarm->seconds, p_alarm->message);
			printf("After sleeping, the time is: %d\n", time(NULL));
			free(p_alarm);
		}
		else {
			insert_alarm(p_alarm);
		}
	}//end of while
}//end of function
